<template>
  <div>
    <el-button
      v-if="$route.fullPath.indexOf('workflowMGMT') > -1"
      style="position: absolute; top: -10px; right: 5px; z-index: 100"
      type="primary"
      @click="handleSave()"
      >保存</el-button
    >
    <div
      style="
        width: 100%;
        height: 100%;
        min-height: 300px;
        overflow: hidden;
        position: relative;
      "
      ref="Graph"
    ></div>
  </div>
</template>

<script>
// import echarts from "echarts";
import * as echarts from "echarts";
import resize from "@/views/dashboard/mixins/resize";
import { getDataList, baseRequest, getData } from "@/api/dynamic/dynamic";

var that;

export default {
  inject: ["app"],
  name: "flowChart",
  mixins: [resize],
  props: {
    workflowid: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      workflow: null,
      chart: null,
      nodeList: [],
      nodeListById: {},
      taskList: [],
      reject: [],
      nodePath: [],
      levels: {
        maxLevelLength: 0,
      },
      startNodes: [],
      lines: [],
      getUrl: "",
      draggers: {
        flag: false,
        x: 0,
        y: 0,
      },
    };
  },
  created() {
    let type = this.$route.query.type;
    let type2 = "nodeFlowChartList";
    if (type) {
      if (type.indexOf("workflow") == -1) {
        type = "workflow";
        type2 = "documentNodeFlowChartList";
      } else {
        type = type.split("/")[1];
      }
      this.getUrl =
        "/" + type + "/" + type2 + "?workflowid=" + this.$route.params.Id;
    }
    if(this.$route.query.type){
      getData(this.$route.query.type, this.$route.params.Id).then((response) => {
        if (response.code == 200) {
          this.workflow = response.data;
          this.getNodeList();
        }
      });
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });

    that = this;
    this.mouseUpListener = document.addEventListener(
      "mouseup",
      this.HandledragEnd.bind(this)
    );
    this.mouseMoveListener = document.addEventListener(
      "mousemove",
      this.Handledrag.bind(this)
    );
    this.HandledragEnd = this.app.$on("root-mousemove", this.resizerMouseMove);
    this.Handledrag = this.app.$on("root-mouseup", this.resizerMouseUp);
  },
  beforeDestroy() {
    document.removeEventListener("mouseup", this.HandledragEnd);
    document.removeEventListener("mousemove", this.Handledrag);
  },
  watch: {
    workflowid: {
      immediate: true,
      handler: function (val) {
        if (val) {
          this.getUrl = "/workflow/nodeFlowChartList?workflowid=" + String(val);
          this.getNodeList();
        }
      },
    },
  },
  methods: {
    getNodeList() {
      getDataList(this.getUrl)
        .then((response) => {
          if (response.code == 200) {
            this.nodeList = response.data.nodeList;
            this.reject = response.data.Reject;
            this.nodePath = response.data.workflowPath || []
            this.taskList = response.data.task || [];
            if (this.nodeList.length > 0) {
              this.updateNodeList();
            }
          }
        })
        .catch(() => {});
    },
    updateNodeList() {
      this.resetNodeTree();
      // this.makeNodeTree()
      this.makeNodeTrees(this.startNodes, 0);
      this.makeNodeData();
    },
    resetNodeTree() {
      this.nodeList.forEach((item, index) => {
        item.name = item.nodeName;
        item.x = item.x || 0;
        item.y = item.y || 0;
        item.level = 0;
        item.index = index;
        item.draggable = true;
        item.fixed = true;
        if (!Array.isArray(item.toidArray)) {
          item.toidArray = item.toidArray ? item.toidArray.split(",") : [];
          item.fromidArray = item.fromidArray
            ? item.fromidArray.split(",")
            : [];
        }
        let state = this.dataFormat("stateid", item.stateid);
        if (state == "创建") {
          if (item.responseType == "拒绝") {
            item.itemStyle = { color: "#F56C6C" };
          }
        } else if (state == "活动") {
          item.itemStyle = { color: "#F9A80C" };
        } else if (state == "完成") {
          item.itemStyle = { color: "#067B04" };
        }
        if (item.name == "开始节点") {
          item.itemStyle = { color: "#67C23A" };
        }
        if (item.name == "结束节点") {
          item.itemStyle = { color: "#409EFF" };
        }
        if (item.fromidArray.length == 0) {
          this.startNodes.push(item);
        }
        this.nodeListById[item.id] = item;
      });
      if (this.nodePath.length > 0) {
        for (let line of this.nodePath) {
          this.lines.push({
            source: this.nodeListById[line.fromid].index,
            target: this.nodeListById[line.toid].index,
            nodeName: this.nodeListById[line.fromid].name+'>'+this.nodeListById[line.toid].name,
            label:{
              show:true,
              formatter(params){
                if(params.data.operationType!='Reject'&&params.data.roadFlag){
                  if(params.data.roadAttribute){
                    return params.data.roadAttribute.split('==')[1]||params.data.roadAttribute
                  }
                  return params.data.roadFlag
                }
                return ''
              },
              fontSize:'small',
            },
            lineStyle: {
              color: line.operationType=='Reject'?"#F56C6C":this.getLineStyle(this.nodeListById[line.fromid], this.nodeListById[line.toid]),
              curveness:line.operationType=='Reject'?0.2:0
            },
            ...line
          });
        }
      }
      // if (this.reject.length > 0) {
      //   for (let line of this.reject) {
      //     this.lines.push({
      //       source: this.nodeListById[line.fromid].index,
      //       target: this.nodeListById[line.toid].index,
      //       nodeName: this.nodeListById[line.fromid].name+'>'+this.nodeListById[line.toid].name,
      //       lineStyle: {
      //         curveness: 0.2,
      //         color: "#F56C6C",
      //       },
      //     });
      //   }
      // }
    },
    makeNodeTree() {
      for (let current of this.nodeList) {
        if (current.toidArray.length > 0) {
          let level = current.level;
          for (let item of current.toidArray) {
            let node = this.nodeListById[Number(item)];
            // this.lines.push({
            //   source: current.index,
            //   target: node.index,
            //   lineStyle: {
            //     color: this.getLineStyle(current, node),
            //   },
            // });
            // if(node.level == 0)this.levels[0]=[node.id]
            if (node.level <= level) {
              node.level = current.level + 1;
              this.levels[node.level]
                ? this.levels[node.level].push(node.id)
                : (this.levels[node.level] = [node.id]);
              if (
                this.levels[node.level].length > this.levels["maxLevelLength"]
              ) {
                this.levels["maxLevelLength"] = this.levels[node.level].length;
              }
            }
          }
          if (current.level == 0) this.levels[0] = [current.id];
        }
      }
    },
    // 广度优先遍历
    makeNodeTrees(startNodes, i) {
      if (i == 0) {
        this.levels[i] = startNodes.map((node) => node.id);
        this.levels["maxLevelLength"] = this.levels[i].length;
      }
      if (startNodes.length > 0) {
        var newStartNodes = [];
        for (let currentNode of startNodes) {
          if (i != 0 && currentNode.level == 0) {
            currentNode.level = i;
            if (this.levels[i]) {
              if (!this.levels[i].includes(currentNode.id))
                this.levels[i].push(currentNode.id);
            } else this.levels[i] = [currentNode.id];
            if (this.levels[i].length > this.levels["maxLevelLength"]) {
              this.levels["maxLevelLength"] = this.levels[i].length;
            }
          }
          if (currentNode.toidArray.length > 0) {
            for (let childid of currentNode.toidArray) {
              let childNode = this.nodeListById[Number(childid)];
                if(this.nodePath.length==0){
                  this.lines.push({
                    source: currentNode.index,
                    target: childNode.index,
                    nodeName:currentNode.name+'>'+childNode.name,
                    lineStyle: {
                      color: this.getLineStyle(currentNode, childNode),
                    },
                  });
                }
              if (childNode.level == 0 && !newStartNodes.includes(childNode)) {
                newStartNodes.push(childNode);
              }
            }
          } else {
            continue;
          }
        }
        this.makeNodeTrees(newStartNodes, i + 1);
      }
      return;
    },
    getLineStyle(current, next) {
      let currentState = this.dataFormat("stateid", current.stateid);
      let nextState = this.dataFormat("stateid", next.stateid);
      if (currentState == "完成") {
        if (nextState == "完成") {
          return "#067B04";
        } else if (nextState == "活动") {
          return "#F9A80C";
        }
      }
    },
    makeNodeData() {
      // if (this.workflow&&(this.workflow.defaultAxis == "1" || typeof this.workflow.defaultAxis=="undefined")) {
        let maxLevelLength = this.levels["maxLevelLength"];
        for (let node of this.nodeList) {
          let currentLength = this.levels[node.level].length;
          node.x = 100 * node.level;
          let index = this.levels[node.level].indexOf(node.id);
          node.y = 50 * (2 * (index + 1) + maxLevelLength - currentLength);
        }
      // }
      if (this.chart) this.setOption();
    },
    initChart() {
      this.chart = echarts.init(this.$refs.Graph);
      this.setOption();
    },
    setOption() {
      this.chart.setOption({
        tooltip: {
          formatter(params) {
            let content = `名称：${params.data.nodeName}<br>`;
            if (params.data.roleId) {
              content += `角色：${
                that.$store.state.optionInfo.Roles.filter(
                  (item) => item.roleId == params.data.roleId
                )[0].roleName
              }<br/>`;
            }
            if (params.data.userId) {
              content += `审批者：${
                that.dataFormat('ownerid',params.data.userId)
              }<br/>`;
            }
            let task = that.taskList.filter(
              (item) => item.nodeid == params.data.id
            );
            if (task.length > 0) {
              content += `状态：${that.dataFormat(
                "stateid",
                task[0].stateid
              )}<br>启动时间：${task[0].startTime}<br>${task[0].accomplishTime?'完成时间：'+task[0].accomplishTime+'<br>耗时：'+task[0].costTimeDay:''}`;
            }else{
              content += params.data.createTime?`创建时间：${params.data.createTime}`:'';
            }
            return content;
          },
        },
        animationDurationUpdate: 0,
        animationEasingUpdate: "quinticInOut",
        series: [
          {
            type: "graph",
            layout: "none",
            symbolSize: 60,
            roam: false,
            label: {
              show: true,
            },
            edgeSymbol: ["circle", "arrow"],
            edgeSymbolSize: [4, 10],
            edgeLabel: {
              fontSize: 20,
            },
            data: this.nodeList,
            links: this.lines,
            lineStyle: {
              width: 2,
            },
            itemStyle: {
              color: "#ccc",
            },
          },
        ],
      });
      this.chart.on("mousedown", function (params) {
        that.draggers.flag = true;
        params.event.target.draggable = true;
        that.draggers.x = params.event.offsetX;
        that.draggers.y = params.event.offsetY;
        that.draggers.id = params.data.id;
      });
    },
    handleSave() {
      // console.log(this.nodeList.map(item => {
      //     return {
      //       id: item.id,
      //       x: Math.floor(item.x),
      //       y: Math.floor(item.y),
      //       workflowid: item.workflowid,
      //     };
      //   }));
      // return
      baseRequest(
        "/pms/workflowMGMT/modifyNodeList",
        "put",
        {},
        this.nodeList.map(item => {
          return {
            id: item.id,
            x: Math.floor(item.x),
            y: Math.floor(item.y),
            workflowid: item.workflowid,
          };
        })
      ).then((response) => {
        if (response.code == 200) {
          this.msgSuccess(response.msg);
          // this.refreshCurrent();
          this.getNodeList();
        } else {
          this.msgError(response.msg);
        }
      });
    },
    Handledrag(event) {
      if (this.draggers.flag) {
        // console.log(event);return
        const realWidth = this.$refs.Graph.offsetWidth;
        // const realHeight = this.$refs.Graph.offsetHeight;
        const insetWidth = this.$refs.Graph.children[0].children[0].width;
        // const insetHeight = this.$refs.Graph.children[0].children[0].height;
        this.nodeListById[this.draggers.id].x =
        // (event.offsetX - this.draggers.x) +
        //   this.nodeListById[this.draggers.id].x;
          ((event.offsetX - this.draggers.x) / insetWidth) * realWidth +
          this.nodeListById[this.draggers.id].x;
        this.nodeListById[this.draggers.id].y =
        (event.offsetY - this.draggers.y) +
          this.nodeListById[this.draggers.id].y;
          // ((event.offsetY - this.draggers.y) / realHeight) * insetHeight +
          // this.nodeListById[this.draggers.id].y;
        this.draggers.x = event.offsetX;
        this.draggers.y = event.offsetY;
        this.setOption();
        // this.chart.resize();
      }
    },
    HandledragEnd(event) {
      if (that.draggers.flag) {
        that.draggers.flag = false;
      }
    },
  },
};
</script>